import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.StringTokenizer;

/**
 * @author Simon
 * Generate the data by given a file path of data file
 * The data is store at Array dataset
 */
public class Data {
	public ArrayList<double[]> dataset = new ArrayList<double []>();
	public int attributeNum;

	private int[] sa_ran_array;

	public Data(){
		
	}
//	
	public Data(String path){
		try{
			BufferedReader f = new BufferedReader(new FileReader(path));
	        // input file name goes above
					
			String line = f.readLine();
			StringTokenizer st;

			while (line != null){
				st = new StringTokenizer(line);	
				int n = st.countTokens();
				attributeNum = n;
				double[] tuple = new double[n];
				for (int i = 0; i < n; i++){
					tuple[i] = Double.parseDouble(st.nextToken());
				}
				dataset.add(tuple);
				line = f.readLine();
			}
		} catch (Exception e){
			e.printStackTrace();
		}
	}
	
	/**
	 * @param network the network to evaluate
	 * @return the accuracy of this dataset
	 */
	public double calMisRecord(Network network){
		int yes = 0;
		int no = 0;
		for (int i = 0; i < dataset.size(); i++){
			if (network.testTuple(dataset.get(i))){
				yes++;
			} else {
				no++;
			}
		}
		return (double)yes / (yes+no);
	}
	/**
	 * randomly generate samples for sa(simulated annealing) to calculate error
	 */
	public void genSaRandomArray(){
        Random seed=new Random();
        Map<Integer, Integer> hm=new HashMap<Integer, Integer>();
        int sa_size=(dataset.size()>10000)?(dataset.size()/10):dataset.size();
        this.sa_ran_array=new int[sa_size];
        for(int i=0;i<sa_ran_array.length;i++){
            int index=0;
          while(hm.containsKey(index)){
              index= Math.abs(seed.nextInt()) % dataset.size();
          }
          hm.put(index, 1);
          this.sa_ran_array[i]=index;
        }
    }
    
    public int calSaError(Network network){
        double res=0.0;
        for (int i = 0; i < sa_ran_array.length; i++){
            res += network.getErrSquare(dataset.get(sa_ran_array[i]));
        }
        res = res/2;
        return (int)res;
    }
}
